﻿#include "utilities.h"

#include <random>
#include <ranges>

#include <vsg/maths/common.h>

vsg::vec4 ColorFromHSV(double hue, double saturation, double value)
{
	vsg::vec4 color = { 0.f, 0.f, 0.f, 1.f };

	// Red channel
	double k = fmod((5.0f + hue / 60.0f), 6);
	double t = 4.0f - k;
	k = (t < k) ? t : k;
	k = (k < 1) ? k : 1;
	k = (k > 0) ? k : 0;
	color.r = value - value * saturation * k;

	// Green channel
	k = fmod((3.0f + hue / 60.0f), 6);
	t = 4.0f - k;
	k = (t < k) ? t : k;
	k = (k < 1) ? k : 1;
	k = (k > 0) ? k : 0;
	color.g = value - value * saturation * k;

	// Blue channel
	k = fmod((1.0f + hue / 60.0f), 6);
	t = 4.0f - k;
	k = (t < k) ? t : k;
	k = (k < 1) ? k : 1;
	k = (k > 0) ? k : 0;
	color.b = value - value * saturation * k;

	return color;
}

vsg::dvec3 ColorToHSV(vsg::vec4 color)
{
	vsg::dvec3 hsv = { 0.f, 0.f, 0.f };
	vsg::dvec3 rgb = { color.r, color.g, color.b };
	double min, max, delta;

	min = rgb.x < rgb.y ? rgb.x : rgb.y;
	min = min < rgb.z ? min : rgb.z;

	max = rgb.x > rgb.y ? rgb.x : rgb.y;
	max = max > rgb.z ? max : rgb.z;

	hsv.z = max;            // Value
	delta = max - min;

	if (delta < 0.00001f)
	{
		hsv.y = 0.0f;
		hsv.x = 0.0f;       // Undefined, maybe NAN?
		return hsv;
	}

	if (max > 0.0f)
	{
		// NOTE: If max is 0, this divide would cause a crash
		hsv.y = (delta / max);    // Saturation
	}
	else
	{
		// NOTE: If max is 0, then r = g = b = 0, s = 0, h is undefined
		hsv.y = 0.0f;
		hsv.x = NAN;        // Undefined
		return hsv;
	}

	// NOTE: Comparing double values could not work properly
	if (rgb.x >= max) hsv.x = (rgb.y - rgb.z) / delta;    // Between yellow & magenta
	else
	{
		if (rgb.y >= max) hsv.x = 2.0f + (rgb.z - rgb.x) / delta;  // Between cyan & yellow
		else hsv.x = 4.0f + (rgb.x - rgb.y) / delta;      // Between magenta & cyan
	}

	hsv.x *= 60.0f;     // Convert to degrees

	if (hsv.x < 0.0f) hsv.x += 360.0f;

	return hsv;
}

vsg::dvec3 Polar3DToXYZRandom(Polar3D polar) {
	double RadAlpha = vsg::radians(polar.alpha);
	double RadBeta = vsg::radians(polar.beta);
	std::random_device rd;  // 将用于获得随机数引擎的种子
	std::mt19937_64 gen(rd()); // 以 rd() 播种的标准 mersenne_twister_engine
	std::normal_distribution<> d{ 5, 10 };
	double z = polar.length * sin(RadAlpha) + d(gen);
	double xy = polar.length * cos(RadAlpha);
	double x = xy * cos(RadBeta) + d(gen);
	double y = xy * sin(RadBeta) + d(gen);
	return { x, y, z };
}

vsg::dvec3 Polar3DToXYZ(Polar3D polar) {
	double RadAlpha = vsg::radians(polar.alpha);
	double RadBeta = vsg::radians(polar.beta);
	double z = polar.length * sin(RadAlpha);
	double xy = polar.length * cos(RadAlpha);
	double x = xy * cos(RadBeta);
	double y = xy * sin(RadBeta);
	return { x, y, z };
}

std::pair<vsg::dvec3, vsg::dvec3> getOtherNormal(vsg::dvec3 normal) {
	vsg::dvec3 a = cross(normal, { 1, 0, 0 });
	if (a.x == 0 && a.y == 0 && a.z == 0) {
		a = cross(normal, { 0, 1, 0 });
	}
	vsg::dvec3 b = cross(normal, a);
	a = normalize(a);
	b = normalize(b);
	return { a, b };
}

// 获取给定圆心、半径、点数的同z平面圆
std::vector<vsg::dvec3> genCirclePos(vsg::dvec3 center, double radius, uint8_t posCount) {
	double theta = 0;
	double deltTheta = 360. / posCount;
	std::vector<vsg::dvec3> res{ posCount };
	for (auto i : std::views::iota(0) | std::views::take(posCount)) {
		double radTheta = vsg::radians(theta);
		double x = center.x + radius * sin(radTheta);
		double y = center.y + radius * cos(radTheta);
		double z = center.z;
		res[i] = { x, y, z };
		theta += deltTheta;
	}
	return res;
}

// 获取给定任意法向量以及圆心、半径的圆离散点
std::vector<vsg::dvec3> getNormalCirclePos(vsg::dvec3 circlePos, double radius, vsg::dvec3 normal, double startAngle, double endAngle, uint8_t pointCount) {
	std::vector<vsg::dvec3> res{ pointCount };
	auto [a, b] = getOtherNormal(normal);
	double deltAngle = (endAngle - startAngle) / pointCount;
	double alphaDeg = startAngle;
	vsg::dvec3 pointPos;
	double alpha;
	//	for (int i = 0; i < pointCount; ++i) {
	//		alpha = vsg::radians(alphaDeg;
	//		pointPos.x = circlePos.x + radius * a.x * cos(alpha) + radius * b.x * sin(alpha);
	//		pointPos.y = circlePos.y + radius * a.y * cos(alpha) + radius * b.y * sin(alpha);
	//		pointPos.z = circlePos.z + radius * a.z * cos(alpha) + radius * b.z * sin(alpha);
	//		alphaDeg += deltAngle;
	//		res[i] = pointPos;
	//	}
	for (auto i : std::views::iota(0) | std::views::take(pointCount)) {
		alpha = vsg::radians(alphaDeg);
		pointPos.x = circlePos.x + radius * a.x * cos(alpha) + radius * b.x * sin(alpha);
		pointPos.y = circlePos.y + radius * a.y * cos(alpha) + radius * b.y * sin(alpha);
		pointPos.z = circlePos.z + radius * a.z * cos(alpha) + radius * b.z * sin(alpha);
		alphaDeg += deltAngle;
		res[i] = pointPos;
	}
	return res;
}

std::vector<vsg::dvec3> getRosebushPos(vsg::dvec3 rosebushPos, vsg::dvec3 normal, double radius, uint8_t bushCount) {
	auto [normalX, normalY] = getOtherNormal(normal);
	vsg::dmat3 modelCoordinateAxisBase = {
		normalX.x, normalY.x, normal.x,
		normalX.y, normalY.y, normal.y,
		normalX.z, normalY.z, normal.z
	};

	// r = cos(a*theta);
	// x = r*cos(theta)
	// y = r*sin(theta)
	// z = a/2*sin(a*theta) Or z = r*sin(a*theta) Or z = 0
	int pointCount = 200 * bushCount;
	double deltTheta = 360. / pointCount;
	double theta = 0;
	std::vector<vsg::dvec3> res(pointCount);
	vsg::dvec3 pointPos;
	double thetaRad;
	for (auto i : std::views::iota(0) | std::views::take(pointCount)) {
		thetaRad = vsg::radians(theta);
		theta += deltTheta;
		double r = radius * cos(bushCount * thetaRad);
		pointPos = { r * cos(thetaRad), r * sin(thetaRad), 0 };
		pointPos = modelCoordinateAxisBase * pointPos;
		pointPos = pointPos + rosebushPos;
		res[i] = pointPos;
	}

	return res;
}

std::vector<vsg::dvec3> getNormalConePos(vsg::dvec3 circlePos, vsg::dvec3 vertexPos, double radius) {
	std::random_device rd;  // 将用于获得随机数引擎的种子
	std::mt19937_64 gen(rd()); // 以 rd() 播种的标准 mersenne_twister_engine
	std::uniform_int_distribution<> heightCountDis(-10, 10);
	std::uniform_int_distribution<> alphaCountDis(10, 20);
	std::vector<vsg::dvec3> res;
	vsg::dvec3 normal = vertexPos - circlePos;
	vsg::dvec3 normalizationNormal = normalize(normal);
	auto [a, b] = getOtherNormal(normalizationNormal);
	double height = length(normal);
	uint8_t heightCount = 20 + heightCountDis(gen);
	uint8_t circleCount = 20 + alphaCountDis(gen);
	double deltHeight = height / (heightCount - 1);
	double deltAngle = 360.0f / circleCount;
	double angle = 0.0f;
	double heightNow = 0.0;
	vsg::dvec3 pointPos;
	for (int i = 0; i < heightCount; ++i) {
		for (int j = 0; j < circleCount; ++j) {
			double alpha = vsg::radians(angle);
			pointPos.x = circlePos.x + radius * a.x * cos(alpha) + radius * b.x * sin(alpha);
			pointPos.y = circlePos.y + radius * a.y * cos(alpha) + radius * b.y * sin(alpha);
			pointPos.z = circlePos.z + radius * a.z * cos(alpha) + radius * b.z * sin(alpha);
			angle += deltAngle;
			res.push_back(pointPos);
		}
		heightNow += deltHeight;
		circlePos = circlePos + normalizationNormal * heightNow;
		radius = radius * (height - heightNow) / height;
	}
	return res;
}

vsg::dvec3 getRandomNormal(double startAlpha, double endAlpha, double startBeta, double endBeta) {
	std::random_device rd;  // 将用于获得随机数引擎的种子
	std::mt19937_64 gen(rd()); // 以 rd() 播种的标准 mersenne_twister_engine
	std::uniform_real_distribution<double> alphaDis(startAlpha, endAlpha);
	std::uniform_real_distribution<double> betaDis(startBeta, endBeta);

	return Polar3DToXYZ({ 1, alphaDis(gen), betaDis(gen) });
}

vsg::vec4 getRandomColor() {
	std::random_device rd;  // 将用于获得随机数引擎的种子
	std::mt19937_64 gen(rd()); // 以 rd() 播种的标准 mersenne_twister_engine
	std::uniform_real_distribution<double> colorHDis{ 0, 360 };


	double H = colorHDis(gen);
	double S = 0.5;
	double V = 0.5;
	vsg::vec4 color = ColorFromHSV(H, S, V);
	return color;
}

std::vector<vsg::dvec3> getBallPos(vsg::dvec3 ballPos, double radius, uint8_t alphaCount, uint8_t betaCount) {
	double alpha = 90;
	double deltAlpha = 180. / alphaCount;
	double beta = 0.;
	double deltBeta = 360.0 / betaCount;
	std::vector<vsg::dvec3> res;
	for (int i = 0; i <= alphaCount; ++i) {
		for (int j = 0; j < betaCount; ++j) {

			vsg::dvec3 relatePos = Polar3DToXYZ({
				radius, alpha, beta
				});
			vsg::dvec3 pointPos = ballPos + relatePos;
			res.push_back(pointPos);

			beta += deltBeta;
		}
		alpha -= deltAlpha;
	}
	return res;
}

std::vector<vsg::dvec3> getSpeedlistFromPoslist(vsg::dvec3 corePos, double speedNorm, const std::vector<vsg::dvec3>& posList) {
	std::vector<vsg::dvec3> res;
	for (const vsg::dvec3& pointPos : posList) {
		vsg::dvec3 direction = normalize(pointPos - corePos);
		vsg::dvec3 speed = direction * speedNorm;
		res.push_back(speed);
	}
	return res;
}

std::vector<vsg::dvec3> getSpeedListFormPoslistWithRatio(vsg::dvec3 corePos, double ratio, const std::vector<vsg::dvec3>& posList) {
	std::vector<vsg::dvec3> res;
	for (const vsg::dvec3& pointPos : posList) {
		vsg::dvec3 direction = normalize(pointPos - corePos);
		double distance = length(pointPos - corePos);
		vsg::dvec3 speed = direction * (distance * ratio);
		res.push_back(speed);
	}
	return res;
}

bool isToDo(double iterRatio) {
	std::random_device rd;  // 将用于获得随机数引擎的种子
	std::mt19937_64 gen(rd()); // 以 rd() 播种的标准 mersenne_twister_engine
	std::uniform_real_distribution<double> iterIsDis(0, 1);
	if (iterIsDis(gen) > iterRatio) {
		return true;
	}
	else {
		return false;
	}
	return true;
}

std::vector<vsg::dvec3> getHeartPos(vsg::dvec3 heartPos, vsg::dvec3 normal, double radius, uint8_t pointCount) {
	std::vector<vsg::dvec3> res;
	return res;
}
